#include "Engine.h"

// Redefinition static
Engine* Engine::instance = 0;

Engine::Engine()
	: isInitialized(false)
	, quit(false)
{
	
}

void Engine::Init()
{
	event = new SDL_Event();

	if (SDL_Init(SDL_INIT_EVERYTHING))
	{
		std::cout << SDL_GetError() << std::endl;
	}

	if (TTF_Init() != 0){
		std::cout << SDL_GetError() << std::endl;
	}

	window = SDL_CreateWindow("Hello World"
		, SDL_WINDOWPOS_CENTERED
		, SDL_WINDOWPOS_CENTERED
		, DEFAULT_WIN_W, DEFAULT_WIN_H
		, SDL_WINDOW_SHOWN);
	if (window == nullptr)
	{
		std::cout << SDL_GetError() << std::endl;
	}

	renderer = SDL_CreateRenderer(window, -1
		, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
	if (renderer == nullptr)
	{
		std::cout << SDL_GetError() << std::endl;
	}

	SetRenderClear(101, 156, 239, 255);

	isInitialized = true;
}

Engine::~Engine()
{
	SDL_DestroyRenderer(renderer);
	SDL_DestroyWindow(window);
	TTF_Quit();
	SDL_Quit();
}

void Engine::Run()
{
	while (!quit)
	{
		InputEvent* inputEvent = InputEvent::get_event();
		if (inputEvent != nullptr)
		{
			if (inputEvent->is_window_closing())
			{
				quit = true;
			}

			// Broadcast event to all components
			std::vector<Component* const>::const_iterator iter;
			for (iter = Component::GetComponentsPtr()->begin()
				; iter != Component::GetComponentsPtr()->end()
				; iter++
				)
			{
				(*iter)->NotifyInput(*inputEvent);
			}
		}

		if (InputEvent::is_key_down(InputEvent::KEY_ESCAPE)) 
		{
			quit = true;
		}

		Timer::GetInstance()->Tick();

		Update(Timer::GetInstance()->GetDeltaTime());
		Draw();
	}

	// If the engine is not running anymore, stop it, but dont kill
	Stop();
}

void Engine::Start()
{
	std::vector<Component* const>::const_iterator iter;
	for (iter = Component::GetComponentsPtr()->begin()
		; iter != Component::GetComponentsPtr()->end()
		; iter++
		)
	{
		(*iter)->Start();
	}
	Run();
}

void Engine::Update(float dt)
{
	std::vector<Component* const>::const_iterator iter;
	for (iter = Component::GetComponentsPtr()->begin()
		; iter != Component::GetComponentsPtr()->end()
		; iter++
		)
	{
		(*iter)->Update(dt);
	}
}

void Engine::Draw()
{
	SDL_RenderClear(renderer);

	std::vector<Component* const>::const_iterator iter;
	for (iter = Component::GetComponentsPtr()->begin()
		; iter != Component::GetComponentsPtr()->end()
		; iter++
		)
	{
		(*iter)->Draw();
	}

	SDL_RenderPresent(renderer);
}

void Engine::Stop()
{
	std::vector<Component* const>::const_iterator iter;
	for (iter = Component::GetComponentsPtr()->begin()
		; iter != Component::GetComponentsPtr()->end()
		; iter++
		)
	{
		(*iter)->Stop();
	}

	isInitialized = false;
	Component::ClearComponents();
}

